package org.interfaceadaptation.parameter.expression.impl;

import org.interfaceadaptation.parameter.expression.Context;
import org.interfaceadaptation.util.ReflectionUtils;


public class Root extends AbstractExpression {

	private Class<?> baseClass;
	private String name;

	public Root(Class<?> baseClass) {
		super(null);
		this.baseClass = baseClass;
	}

	public Root(Class<?> baseClass,String name) {
		super(null);
		this.baseClass = baseClass;
		this.name = name;
	}

	
	@Override
	public Object getValue(Context context) {
		if (context.getRoot() != null) {
		    getRootContext(context).setRoot(context.getRoot());
		}
		else {
			if (getRootContext(context).rootNotAssigned()) {
				Object root = ReflectionUtils.newInstance(getReturnType());
                context.setRoot(root);
                getRootContext(context).setRoot(root);
			}
			else {
				context.setRoot(getRootContext(context).getRoot());
			}
		}
		return context.getRoot();
	}

	@Override
	public void setValue(Context context, Object value) {
		context.setRoot(value);
		getRootContext(context).setRoot(value);
	}

	public Class<?> getReturnType() {
		return baseClass;
	}

	public Class<?> getGenericReturnType() {
		return null;
	}

	@Override
	protected RootContext createExpressionContext(Context context) {
		return new RootContext(this);
	}

	@Override
	public String getDefaultNodeName() {
		return name==null?baseClass.getSimpleName():name;
	}
	
	public RootContext getRootContext(Context context) {
	    return (RootContext) getExpressionContext(context);
	}

	
}
